import 'dart:io';

import 'package:flutterlib/model/oss_token.dart';

import 'oss_credential.dart';
import 'package:flutter/material.dart';

typedef FederationCredentialFetcher = Future<OssToken> Function(
    String authServerUrl);

class OSSAuthCredentialProvider {
  OSSAuthCredentialProvider.init({
    @required String authServerUrl,
    @required FederationCredentialFetcher fetcher,
  })  : assert(authServerUrl?.isNotEmpty ?? false),
        assert(fetcher != null),
        _authServerUrl = authServerUrl,
        _fetcher = fetcher;

  final String _authServerUrl;
  final FederationCredentialFetcher _fetcher;

  OSSCredential _cachedCredential;

  Future<OSSCredential> getCredential() async {
    OSSCredential validCredential;
    if (_cachedCredential == null) {
      _cachedCredential = await _fetchCredential();
    } else {
      if (_checkExpire(_cachedCredential.expiration)) {
        _cachedCredential = await _fetchCredential();
      }
    }
    validCredential = _cachedCredential;
    if (validCredential == null) {
      return Future.error(HttpException('获取sts token失败'));
    }
    return validCredential;
  }

  Future<OSSCredential> _fetchCredential() async {
    final OssToken json = await _fetcher(_authServerUrl);

    // FIXME: 测试
    final expiration = json.expiration.replaceAll(' UTC', '');
    OSSCredential credential = OSSCredential(
      accessKeyId: json.accessKeyId,
      accessKeySecret: json.accessKeySecret,
      securityToken: json.securityToken,
      expiration: expiration,
    );
    return credential;
  }

  // 检查是否过期
  bool _checkExpire(String expiration) {
    if (expiration?.isEmpty ?? true) {
      return false;
    }
    final expirationDate = DateTime.parse(expiration);
    final difference = expirationDate.difference(DateTime.now().toUtc());

    // 剩余时间小于两分钟，则需要刷新
    if (difference.inMinutes <= 2) {
      return true;
    }
    return false;
  }
}
